#include <stdio.h>
#include "sock.h"
#include "protocol.h"

#define SIO_RCVALL  (0x80000000 | (0x18000000) | (1))

void decode_tcp_packet(char *packet, const char *src_ip, const char *dst_ip)
{
	tcp_header_t *tcp_hdr = (tcp_header_t *)packet;

	printf("src(%s:%d) -> dst(%s:%d) proto(%s)\n", src_ip, ntohs(tcp_hdr->src_port), dst_ip, ntohs(tcp_hdr->dst_port), "TCP");
	//printf(" Port: %d -> %d \n", ntohs(tcp_hdr->src_port), ntohs(tcp_hdr->dst_port));
	
	switch(::ntohs(tcp_hdr->dst_port))
	{
	case 21:
		break;
	case 80:
	case 8080:
		break;
	}
}
//#define RED "\033[0;32;31m"
void decode_ip_packet(char *packet)
{
	ip_header_t *ip_hdr = (ip_header_t*)packet;
	in_addr source, dest;
	char src_ip[32], dst_ip[32];

	source.S_un.S_addr = ip_hdr->src_ip;
	dest.S_un.S_addr = ip_hdr->dst_ip;
	strcpy(src_ip, ::inet_ntoa(source));
	strcpy(dst_ip, ::inet_ntoa(dest));

	int hdr_len = ip_hdr->ihl;
	int proto = ip_hdr->proto;
	//printf("	%s -> %s proto(%d)\n", source_ip, dest_ip, proto);
	switch(proto)
	{
	case IPPROTO_IPV4:
		//printf("	%s -> %s proto(%s)\n", source_ip, dest_ip, "IPPROTO_IPV4");
		break;
	case IPPROTO_TCP: // TCP
		decode_tcp_packet(packet + hdr_len, src_ip, dst_ip);
		break;
	case IPPROTO_UDP:
		//printf("	%s -> %s \n", source_ip, dest_ip);
		break;
	case IPPROTO_ICMP:
		break; 
	}
}

int main()
{
	init_sock(2, 2);

	SOCKET raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

	char hostname[56];
	SOCKADDR_IN addr_in;
	struct  hostent *host;
	gethostname(hostname, 56);
	if((host = gethostbyname((char*)hostname)) == NULL)	
		return 0;

	/* bind socket */
	addr_in.sin_family  = AF_INET;
	addr_in.sin_port    = htons(0);
	memcpy(&addr_in.sin_addr.S_un.S_addr, host->h_addr_list[0], host->h_length);
	printf(" Binding to interface : %s \n", ::inet_ntoa(addr_in.sin_addr));

	if (bind(raw_sock, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)
		return 0;

	u_long arg = 1;
	if(ioctlsocket(raw_sock, SIO_RCVALL, &arg) != 0)	
		return 0;

	/* receive */
	char buff[1024];
	int ret;

	while(1)
	{
		ret = recv(raw_sock, buff, 1024, 0);
		if(ret > 0)
		{
			decode_ip_packet(buff);
		}
	}

	closesocket(raw_sock);

	getchar();
	return 0;
}
